#pragma once

#include "Misc/EngineEditorMacros.h"
#include "Object/Object.h"
#include "EditorContextMenuModel.h"
#include "Math/IntPoint.h"
#include "Framework/Tickable.h"
#include "EditorContextMenuViewModel.m.h"


class RWidget;

//a editor context menu window
RCLASS()
class REditorContextMenuViewModel  : public RObject,ITickable
{
    ROBJECT

public:
    REditorContextMenuViewModel();

    //invoked when menu any visible things changed
    TDelegate<void,int64_t> OnVisibleMenuChanged;

    void SetRootItem(
        const TVector<SEditorContextMenuLine>& InRootItems
        ,SIntPoint InRootMenuScreenPosition
        ,float InRootMenuWidth=200
        ,TDelegate<void> InOnContextMenuClosed=nullptr
        );

    void SetRootItem(
        const TVector<SEditorContextMenuLine>& InRootItems
        ,TSharedObjectPtr<RWidget> InAroundWidget
        ,float InRootMenuWidth
        );

    bool IsEmpty();
    void Clear();
    void OnLostFocus();

    bool IsMenuEmpty(int64_t MenuIndex) const;
    float GetMenuWidth(int64_t InMenuIndex) const;
    int64_t GetMenuHeight(int64_t InMenuIndex) const;
    SIntPoint GetMenuScreenPosition(int64_t InMenuIndex) const;
    int64_t GetMenuLineNum(int64_t InMenuIndex) const;


    const float SepreatorLineHeight=15;
    const float NormalLineHeight=20;
    const float LineHorizontalPadding=10;
    const float LineSpace=5;
    const float IconSize=16;
    const float ExpandIconSize=16;
    TSharedObjectPtr<RTexture2D> GetExpandIcon() const;
    TSharedObjectPtr<RTexture2D> GetIcon(int64_t InMenuIndex,int64_t InLineIndex) const;
    CString GetText(int64_t InMenuIndex,int64_t InLineIndex) const;
    CString GetShorcutText(int64_t InMenuIndex,int64_t InLineIndex) const;
    bool IsExpandIconVisible(int64_t InMenuIndex,int64_t InLineIndex) const;
    bool IsSeparator(int64_t InMenuIndex,int64_t InLineIndex) const;
    bool IsValid(int64_t InMenuIndex,int64_t InLineIndex) const;

    void OnHovered(int64_t InMenuIndex,int64_t InLineIndex);
    void OnUnHovered(int64_t InMenuIndex,int64_t InLineIndex);
    void OnClicked(int64_t InMenuIndex,int64_t InLineIndex);

    bool ShouldHighlight(int64_t InMenuIndex) const;
    int64_t GetHighlightLineIndex(int64_t InMenuIndex) const;

    virtual void Tick(float DeltaSeconds) override;

protected:
    TDelegate<void> OnContextMenuClosed;

    TSharedObjectPtr<RTexture2D> ExpandIcon;
    TVector<SEditorContextMenuLine> RootMenuLines;
    float RootMenuWidth=200;
    SIntPoint RootMenuScreenPosition;

    //Hovored lines per menu
    //can be -1 if no line Hovored
    TVector<int64_t> HovoredLines;

    struct SMenuData
    {
        //can be -1 if no line Selected
        int64_t SelectedLine=-1;

        float Width=200;

        SIntPoint ScreenPosition;

        TVector<SEditorContextMenuLine> Lines;
        //Line index in parent menu
        int64_t LineInParent=0;

    };

    TVector<SMenuData> MenuDatas;

    float ElapsedTime=0;
    int64_t HoveredMenuIndex=-1;
    int64_t HovoredLineIndex=-1;

};